﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using System.Collections;
using System.Xml.Serialization;
using System.Collections.Specialized;

using System.Runtime.Serialization.Json;
using System.Text.RegularExpressions;

namespace OBUCare.Core.Common
{
    public static class Utility
    {

        public static T CreateInstance<T>(string typeName, params object[] args)
        {
            Type type = Type.GetType(typeName);
            if (type == null)
                throw new Exception("can't find type :" + typeName);
            return (T)Activator.CreateInstance(type, args);
        }


        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="t">对象</param>
        /// <returns>xml串</returns>
        public static string Serialize<T>(this T t)
        {
            using (StringWriter sw = new StringWriter())
            {
                XmlSerializer xz = new XmlSerializer(t.GetType());
                xz.Serialize(sw, t);
                return sw.ToString();
            }
        }

        /// <summary>
        /// 序列化对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="t">对象</param>
        /// <returns>xml串</returns>
        public static MemoryStream SerializeToMemoryStream<T>(this T t)
        {
            MemoryStream stream = new MemoryStream();

            XmlSerializer xz = new XmlSerializer(t.GetType());
            xz.Serialize(stream, t);
            return stream;

        }

        public static object Deserialize(this string typeName, string xml)
        {
            Type type = Type.GetType(typeName);
            if (type == null)
                throw new Exception("can't find type :" + typeName);
            return type.Deserialize(xml);
        }

        /// <summary> 
        /// 反序列化为对象 
        /// </summary> 
        /// <param name=\"type\">对象类型</param> 
        /// <param name=\"s\">对象序列化后的Xml字符串</param> 
        /// <returns></returns> 
        public static object Deserialize(this Type type, string s)
        {
            if (s.IsNullOrEmpty())
                return null;
            using (StringReader sr = new StringReader(s))
            {
                XmlSerializer xz = new XmlSerializer(type);
                return xz.Deserialize(sr);
            }
        }

        /// <summary> 
        /// 反序列化为对象 
        /// </summary> 
        /// <param name="type">对象类型</param> 
        ///<param name="xmlFilePath">对象序列化后的xml文件的路径</param>
        /// <returns></returns> 
        public static T Deserialize<T>(this string xmlFilePath)
        {
            using (FileStream fs = new FileStream(xmlFilePath, FileMode.Open))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                var temp = serializer.Deserialize(fs);
                return (T)temp;
            }
        }

        /// <summary>
        /// deep copy any object 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T DeepCopy<T>(this T obj)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(memoryStream, obj);
                memoryStream.Position = 0;
                return (T)formatter.Deserialize(memoryStream);
            }
        }

        /// <summary>
        /// Returns the value of the property
        /// </summary>
        /// <param name="obj">The object whose property value will get from</param>
        /// <param name="propertyName">propertyName of object</param>
        /// <returns>property value</returns>
        public static object GetValue(this object obj, string propertyName)
        {
            try
            {
                if (obj == null)
                    return null;

                Type type = obj.GetType();

                if (string.IsNullOrEmpty(propertyName))
                    return null;

                PropertyInfo property = type.GetProperty(propertyName);

                if (property == null)
                    return null;

                return property.GetValue(obj, null);
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// Sets the value of the property with optional index values for index properties
        /// </summary>
        /// <param name="obj">The object whose property value will be set. </param>
        /// <param name="propertyName">the name of property</param>
        /// <param name="value">The new value for this property</param>
        /// <param name="index">Optional index values for indexed properties. This value should be a null reference for non-indexed properties. </param>
        public static void SetValue(this object obj, string propertyName, object value, object[] index)
        {
            if (obj == null)
                return;

            Type type = obj.GetType();

            if (string.IsNullOrEmpty(propertyName))
                return;

            PropertyInfo property = type.GetProperty(propertyName);

            if (property == null)
                return;
            if (property.CanWrite)
                property.SetValue(obj, value, index);
        }


        /// <summary>
        /// get error message of Exception
        /// </summary>
        /// <param name="ex"></param>
        /// <returns>the error message</returns>
        public static string GetErrorMessage(this Exception ex)
        {
            return string.Format("{0}:{1}", ex.Message, ex.StackTrace);
        }

        /// <summary>
        /// convert a object to int
        /// </summary>        
        /// <param name="obj"></param>
        /// <returns>A Int value.</returns>
        public static bool? ToBoolean(this object obj)
        {
            bool? result = null;
            bool temp = false;
            if (bool.TryParse(obj.ToText(), out temp))
                result = temp;
            return result;
        }

        /// <summary>
        /// Convert current System.Object to Double
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Double? ToDouble(this object obj)
        {

            if (obj == null)
                return null;
            Double? result = null;

            if (obj is Enum)
            {
                result = (Double)obj;
                return result;
            }

            result = obj as Double?;
            if (result == null)
            {
                var temp = obj.ToText();
                if (!string.IsNullOrEmpty(temp))
                {
                    Double tempDouble = 0;
                    if (Double.TryParse(temp, out tempDouble))
                        result = tempDouble;
                }
            }
            return result;
        }

        public static decimal? Todecimal(this object obj)
        {

            if (obj == null)
                return null;
            decimal? result = null;

            if (obj is Enum)
            {
                result = (decimal)obj;
                return result;
            }

            result = obj as decimal?;
            if (result == null)
            {
                var temp = obj.ToText();
                if (!string.IsNullOrEmpty(temp))
                {
                    decimal tempDouble = 0;
                    if (decimal.TryParse(temp, out tempDouble))
                        result = tempDouble;
                }
            }
            return result;
        }
        

        public static void SetValue<Tkey, TValue>(this IDictionary<Tkey, TValue> source, Tkey key, TValue value)
        {
            if (source == null)
                return;
            if (source.ContainsKey(key))
                source[key] = value;
            else
                source.Add(key, value);
        }


        public static TResult GetValue<Tkey, TResult>(this IDictionary<Tkey, TResult> source, Tkey key)
        {
            TResult result = default(TResult);
            if (source != null)
            {
                if (source.ContainsKey(key))
                {
                    if (source[key] is TResult)
                        result = (TResult)source[key];
                }
            }
            return result;
        }



        public static void SetValue(this IDictionary source, object key, object value)
        {
            if (source.Contains(key))
                source[key] = value;
            else
                source.Add(key, value);
        }


        public static T GetValue<T>(this IDictionary source, object key)
        {
            T result = default(T);
            if (source.Contains(key))
            {
                if (source[key] is T)
                    result = (T)source[key];
            }
            return result;
        }


        /// <summary>
        /// Returns a System.String that represents the current System.Object.
        /// </summary>
        /// <typeparam name="T">the Type of obj</typeparam>
        /// <param name="obj"></param>
        /// <returns>A System.String that represents the current System.Object.</returns>
        public static string ToText<T>(this T obj)
        {
            string result = null;
            if (obj is ValueType)
                result = obj.ToString();
            else
            {
                object temp = obj as object;
                if (temp != null)
                    result = temp.ToString();
            }

            return result;
        }

        public static string ToText(this DateTime? obj,string formate)
        {
            string result = null;
            if (obj != null)
            {
                result = obj.Value.ToString(formate);
            }
            return result;
        }

        /// <summary>
        /// convert a object to int
        /// </summary>        
        /// <param name="obj"></param>
        /// <returns>A Int value.</returns>
        public static int? ToInt(this object obj)
        {
            if (obj == null)
                return null;
            int? result = null;

            if (obj is Enum)
            {
                result = (int)obj;
                return result;
            }

            result = obj as int?;
            if (result == null)
            {
                var temp = obj.ToText();
                if (!string.IsNullOrEmpty(temp))
                {
                    int tempInt = 0;
                    if (int.TryParse(temp, out tempInt))
                        result = tempInt;
                }
            }
            return result;
        }

        public static long? ToLong(this object obj)
        {
            if (obj == null)
                return null;
            long? result = null;

            if (obj is Enum)
            {
                result = (long)obj;
                return result;
            }

            result = obj as long?;
            if (result == null)
            {
                var temp = obj.ToText();
                if (!string.IsNullOrEmpty(temp))
                {
                    long tempInt = 0;
                    if (long.TryParse(temp, out tempInt))
                        result = tempInt;
                }
            }
            return result;
        }

        //public static int ToInt(this Enum emun)
        //{
        //    return (int;
        //}

        /// <summary>
        /// Convert current System.Object to DateTime
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static DateTime? ToDateTime(this object obj)
        {
            DateTime? value = null;
            if (obj is DateTime)
                value = obj as DateTime?;
            else
            {
                string tempString = obj.ToText();
                DateTime tempDateTime;
                if (!tempString.IsNullOrEmpty())
                {
                    if (DateTime.TryParse(tempString, out tempDateTime))
                        value = tempDateTime;
                }
            }
            return value;
        }

        /// <summary>
        /// Convert string to Guid
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public static Guid? ToGuid(this string guidString)
        {
            Guid? guid = null;
            if (!string.IsNullOrEmpty(guidString))
            {
                try
                {
                    guid = new Guid(guidString);
                }
                catch
                {
                    guid = null;
                }
            }
            return guid;
        }

        /// <summary>
        /// Convert string to Guid
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public static Guid? ToGuid(this object obj)
        {
            Guid? guid = obj as Guid?;
            if (guid == null || !guid.HasValue)
            {
                string temp = obj.ToText();
                if (!string.IsNullOrEmpty(temp))
                {
                    guid = temp.ToGuid();
                }
            }
            return guid;
        }

        public static byte[] ReadAllBytes(this string filePath)
        {
            if (File.Exists(filePath))
            {
                return File.ReadAllBytes(filePath);
            }
            else
                return null;
        }

        #region Enum Txtension Methods

        

        #endregion

        #region IEnumerable Extension Methods

        /// <summary>
        /// call the method action for each element of a sequence
        /// </summary>
        /// <typeparam name="TSource">the type of element</typeparam>
        /// <param name="source">A sequence that contains elements to perform.</param>
        /// <param name="action">the action that all elements to perform</param>
        public static void Each<TSource>(this IEnumerable source, Action<TSource> action)
        {
            if (source == null)
                return;
            foreach (var o in source)
            {
                if (o is TSource)
                {
                    TSource obj = (TSource)o;
                    action(obj);
                }
            }
        }

        /// <summary>
        /// Filters a value based on a predicate.
        /// </summary>
        /// <typeparam name="TSource">the type of element</typeparam>
        /// <param name="source">An IEnumerable to filter.</param>
        /// <param name="predicate">A function to test each element for a condition.</param>
        /// <returns>an element that satisfy the condition.</returns>
        public static TSource FirstOrDefault<TSource>(this IEnumerable source, Func<TSource, bool> predicate)
        {
            foreach (var o in source)
            {
                if (o is TSource)
                {
                    TSource obj = (TSource)o;
                    if (predicate(obj))
                        return obj;
                }
            }
            return default(TSource);
        }

        /// <summary>
        /// Determines whether a sequence contains a specified element by using a specified predicate
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <param name="source"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static bool Contains<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
        {
            foreach (var o in source)
            {
                if (predicate(o))
                    return true;

            }
            return false;
        }

        /// <summary>
        /// Filters all values based on a predicate.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of source</typeparam>
        /// <param name="source">An System.Collections.Generic.IEnumerable<T> to filter.</param>
        /// <param name="predicate">A function to test each element for a condition.</param>
        /// <returns>An System.Collections.Generic.IEnumerable<T> that satisfy the condition.</returns>
        public static IEnumerable<TSource> FindAll<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
        {
            var query = from e in source
                        where predicate(e)
                        select e;
            return query;
        }

        /// <summary>
        /// call the method action for each element of a sequence
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of source.</typeparam>
        /// <param name="source">A sequence that contains elements to perform.</param>
        /// <param name="action">the action that all elements to perform</param>
        public static void Each<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
        {
            if (source != null)
            {
                foreach (var i in source)
                {
                    action(i);
                }
            }
        }


        public static void Each<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, Action<TSource> action)
        {
            if (source != null)
            {
                foreach (var i in source)
                {
                    if (predicate(i))
                        action(i);
                }
            }
        }

        /// <summary>
        /// Creates an array from a System.Collections.Generic.IEnumerable<T>.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements of source.</typeparam>
        /// <param name="source">An System.Collections.Generic.IEnumerable<T> to create an array from.</param>
        /// <returns>An array that contains the elements from the input sequence.</returns>
        public static TSource[] CustomizeToArray<TSource>(this IEnumerable<TSource> source)
        {
            if (source == null)
            {
                return null;
            }
            else
                return source.ToArray();
        }



        /// <summary>
        /// Adds the elements of the specified collection to the end of the System.Collections.Generic.List<T>.
        /// </summary>
        /// <typeparam name="T">The type of the elements of source.</typeparam>
        /// <param name="source">An System.Collections.Generic.ICollection<T> to add elements.</param>
        /// <param name="collection">The collection whose elements should be added to the end of the System.Collections.Generic.IEnumerable<T>.</param>
        public static void CustomizeAddRange<T>(this ICollection<T> source, IEnumerable<T> collection)
        {
            if (source != null && collection != null)
            {
                collection.Each(item => source.Add(item));
            }
        }

        public static T GetValueTyIndex<T>(this IList<T> source,int index)
        { 
            if(source==null)
            { return default(T); }
            else
            {
                if(index<source.Count)
                    return source[index];
            }
            return default(T);
        }

        #endregion

        public static bool IsNullOrEmpty(this string str)
        {
            return string.IsNullOrEmpty(str);
        }

        public static string  CustomizeTrim(this string str)
        {
            if (str != null)
                return str.Trim();
            else
                return str;
           
        }

        /// <summary>
        ///  使用非递归的方式遍历一颗树
        /// </summary>
        /// <param name="root"></param>
        public static void Traverse<TNode>(TNode root, Func<TNode,IEnumerable<TNode>> getChildNodesHander, Action<TNode> nodeHandler, Func<TNode, Exception, bool> nodeExceptionHandler)
            where TNode:class
        {
            if (root == null)
                return;

            Stack<TNode> nodes = new Stack<TNode>(20);

            nodes.Push(root);

            while (nodes.Count > 0)
            {
                var currentNode = nodes.Pop();
                IEnumerable<TNode> subNodes = null;
                try
                {
                    subNodes = getChildNodesHander(currentNode);

                    if (nodeHandler != null)
                        nodeHandler(currentNode);
                }
                catch (Exception e)
                {
                    var continueTraverse = true;
                    if (nodeExceptionHandler != null)
                        continueTraverse = nodeExceptionHandler(currentNode, e);
                    if (continueTraverse)
                        continue;
                }

                subNodes.Each(n => nodes.Push(n));
            }
        }

        /// <summary>
        /// 生成一串不重复的随机号码
        /// </summary>
        /// <returns></returns>
        public static string CreateRandomNO()
        {
            DateTime nowTime = DateTime.Now;
            System.Random ran = new Random();
            String No = nowTime.Year.ToString() + string.Format("{0:D2}", nowTime.Month) + string.Format("{0:D2}", nowTime.Day) + string.Format("{0:D2}", nowTime.Hour) + string.Format("{0:D2}", nowTime.Minute) + string.Format("{0:D2}", nowTime.Second) + string.Format("{0:D3}", ran.Next(999));
            return No;
        }

        /// <summary>
        /// 将集合中的元素通过分隔符拼接起来
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">要拼接的集合,如：{1，2，3}</param>
        /// <param name="separator">分隔符,如：","</param>
        /// <returns>1,2,3</returns>
        public static string ConcatToString<T>(this IEnumerable<T> source, string separator)
        {
            StringBuilder temp = new StringBuilder();
            source.Each(i => temp.AppendFormat("{0}{1}", separator, i.ToText()));
            if (temp.Length > 1)
                temp = temp.Remove(0, separator.Length);
            return temp.ToString();
        }

        /// <summary>
        /// 将集合中的元素通过分隔符拼接起来
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">要拼接的集合,如：{1，2，3}</param>
        /// <param name="separator">分隔符,如：","</param>
        /// <returns>1,2,3</returns>
        public static string ConcatToString<T>(this IEnumerable<T> source, Func<T,string> getValue,string separator)
        {
            StringBuilder temp = new StringBuilder();
            source.Each(i => temp.AppendFormat("{0}{1}", separator, getValue(i).ToText()));
            if (temp.Length > 1)
                temp = temp.Remove(0, separator.Length);
            return temp.ToString();
        }

        /// <summary>
        /// 返回一个数组中，从from开始到to结束的子数组 for i=from; i<to ; i++
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        public static T[] ToSubArray<T>(this T[] source,int from,int to)
        {
            if (source == null)
                return null;
            List<T> List = new List<T>();
            for (int i = from; i < to;i++ )
            {
                if (source.Length > i)
                    List.Add(source[i]);
                else
                    break;
            }

            return List.CustomizeToArray();
        }

        /// <summary>
        /// 将源集合类型，转为指定的类型的集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="source"></param>
        /// <param name="convertFunc"></param>
        /// <returns></returns>
        public static IList<TResult> ConvertTo<T, TResult>(this IEnumerable<T> source, Func<T, TResult> convertFunc)
        {
            IList<TResult> list = new List<TResult>();
            source.Each(s => 
            {
                TResult r = convertFunc(s);
                list.Add(r);
            });

            return list;
        }



        #region 文件IO相关部分

        public static string GetNewFileName(this string sourceFileName,string newFileNameWithoutExtension)
        {
            string fileExtension = Path.GetExtension(sourceFileName);
            return string.Format("{0}{1}",newFileNameWithoutExtension, fileExtension);
        }

        public static string GetNewRandomFileName(this string sourceFileName)
        {
            string newName = CreateRandomNO();
            return GetNewFileName(sourceFileName, newName);
        }


        /// <summary>
        /// 获取指定路径下的所有文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="recursive">是否递归其子目录</param>
        /// <returns></returns>
        public static IList<FileInfo> GetFiles(this string path, bool recursive)
        {
            IList<FileInfo> files = new List<FileInfo>();
            DirectoryInfo d = new DirectoryInfo(path);
            if (recursive)
            {

                Traverse(d, n => n.GetDirectories(), f => files.CustomizeAddRange(f.GetFiles()), null);
            }
            else
                files.CustomizeAddRange(d.GetFiles());
            return files;
            
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="files"></param>
        /// <param name="isRemove"></param>
        public static void RemoveFiles(this IList<FileInfo> files,Func<FileInfo,bool> isRemove)
        {
            files.Each(f => {
                if (isRemove(f))
                    f.Delete();
            });
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="files"></param>
        /// <param name="isRemove"></param>
        public static void RemoveFiles(this string path, bool recursive, Func<FileInfo, bool> isRemove)
        {
            var files = GetFiles(path, recursive);
            files.RemoveFiles(isRemove);
        }

        #endregion


        public static TimeSpan DateDiff(this DateTime DateTime1, DateTime DateTime2)
        {           
            TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
            TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
            TimeSpan ts = ts1.Subtract(ts2).Duration();           
            return ts;
        }

     
        /// <summary>
        /// this returns a relative difference, meaning that if rValue is greater than lValue, then the return value will be negative
        /// </summary>
        /// <param name="lValue"></param>
        /// <param name="rValue"></param>
        /// <returns></returns>
        public static int MonthDifference(this DateTime lValue, DateTime rValue)
        {
            var temp= (lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year);
            return temp;
        }
        

        /// <summary>
        /// absolute difference
        /// </summary>
        /// <param name="lValue"></param>
        /// <param name="rValue"></param>
        /// <returns></returns>
        public static int ABSMonthDifference(this DateTime lValue, DateTime rValue)
        {
            return Math.Abs((lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year));
        }

        public static string GetValueByName(this NameValueCollection c,string name)
        {
            if (c.AllKeys.Contains(name))
                return c[name];
            else
                return null;
        }

        /// <summary>
        /// 字符转ascii码
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        public static int CharToAscii(this char c)
        {
            string character = c.ToString();
            if (character.Length == 1)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
                return (intAsciiCode);
            }
            else
            {
                throw new Exception("Character is not valid.");
            }
        }

        /// <summary>
        /// ASCII码转字符
        /// </summary>
        /// <param name="asciiCode"></param>
        /// <returns></returns>
        public static char AsciiToChar(this int asciiCode)
        {
            if (asciiCode >= 0 && asciiCode <= 255)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                byte[] byteArray = new byte[] { (byte)asciiCode };
                string strCharacter = asciiEncoding.GetString(byteArray);
                return (strCharacter[0]);
            }
            else
            {
                throw new Exception("ASCII Code is not valid.");
            }
        }

    }


   
    /// <summary>
    /// JSON序列化和反序列化辅助类
    /// </summary>
    public static class JsonHelper
    {
        /// <summary>
        /// JSON Serialization
        /// </summary>
        public static string JsonSerializer<T>(this T t)
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            MemoryStream ms = new MemoryStream();
            ser.WriteObject(ms, t);
            string jsonString = Encoding.UTF8.GetString(ms.ToArray());
            ms.Close();
            //Replace Json Date String                                         
            string p = @"\\/Date\((\d+)\+\d+\)\\/";
            MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
            Regex reg = new Regex(p);
            jsonString = reg.Replace(jsonString, matchEvaluator);
            return jsonString;
        }

        /// <summary>
        /// JSON Deserialization
        /// </summary>
        public static T JsonDeserialize<T>(this string jsonString)
        {
            //Convert "yyyy-MM-dd HH:mm:ss" String as "\/Date(1319266795390+0800)\/"
            string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
            MatchEvaluator matchEvaluator = new MatchEvaluator(
                ConvertDateStringToJsonDate);
            Regex reg = new Regex(p);
            jsonString = reg.Replace(jsonString, matchEvaluator);
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
            T obj = (T)ser.ReadObject(ms);
            return obj;
        }

        /// <summary>
        /// Convert Serialization Time /Date(1319266795390+0800) as String
        /// </summary>
        private static string ConvertJsonDateToDateString(Match m)
        {
            string result = string.Empty;
            DateTime dt = new DateTime(1970, 1, 1);
            dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
            dt = dt.ToLocalTime();
            result = dt.ToString("yyyy-MM-dd HH:mm:ss");
            return result;
        }

        /// <summary>
        /// Convert Date String as Json Time
        /// </summary>
        private static string ConvertDateStringToJsonDate(Match m)
        {
            string result = string.Empty;
            DateTime dt = DateTime.Parse(m.Groups[0].Value);
            dt = dt.ToUniversalTime();
            TimeSpan ts = dt - DateTime.Parse("1970-01-01");
            result = string.Format("\\/Date({0}+0800)\\/", ts.TotalMilliseconds);
            return result;
        }
    }
}